/**
  ******************************************************************************
  * @file    main.c
  * @author  AE Team
  * @version 1.0.3
  * @date    2024-05-28
  * @brief   本样例演示专用固件区读保护功能：调用专用固件保护区提供的API
  *          本样例演示通过包含Slib.h头文件获得专用固件区的接口，
  *          以达到二次开发的目的
  *
  *          二次开发时需要注意FLASH空间，由于专用固件区占用了FLASH末尾的一部分空间，
  *          所以在二次开发时需要减去那部分FLASH空间，例如:该样例中 IROM1 Size 修改为 0xFC00
  *
  *          读保护启用后，无法通过任何方式（CPU、SWD、ISP）读出专用固件区域的内容,
  *          ISP片擦指令将擦除非专用固件区域内的数据，保留专用固件区域内的数据
  *
  * @note    硬件平台：SYM32L010_StartKit_V1.0
  *          接线说明：短接J28
  *
  *          注意： 请重新上下电以确保专用固件区读保护功能开启
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2024 SIYIMicro.
  * All rights reserved.</center></h2>
  *
  *
  ******************************************************************************
  */


/******************************************************************************/
/* Include files                                                              */
/******************************************************************************/
#include "main.h"
#include "sym32l010_hal_sysctrl.h"
#include "sym32l010_hal_systick.h"
#include "sym32l010_hal_gpio.h"
#include "sym32l010_hal_flash.h"
#include "sym32l010_startkit_board.h"
#include "Slib.h"

/******************************************************************************/
/* Local pre-processor symbols/macros ('#define')                             */
/******************************************************************************/

/******************************************************************************/
/* Global variable definitions (declared in header file with 'extern')        */
/******************************************************************************/

/******************************************************************************/
/* Local type definitions ('typedef')                                         */
/******************************************************************************/

/******************************************************************************/
/* Local function prototypes ('static')                                       */
/******************************************************************************/
static void Led_Tog_Error(void);

/******************************************************************************/
/* Local variable definitions ('static')                                      */
/******************************************************************************/

/******************************************************************************/
/* Local pre-processor symbols/macros ('#define')                             */
/******************************************************************************/
#define WRITE_ADDR 0xF000
#define WRITE_VAL  0xABCD5A5A
/******************************************************************************/
/* Function implementation - global ('extern') and local ('static')           */
/******************************************************************************/

HAL_StatusTypeDef HAL_FLASH_SlibConfig(uint32_t StartAddr, uint32_t EndAddr);

/*******************************************************************************
 ** \brief  Main function of project
 **
 ** \return uint32_t return value, if needed
 **
 **
 ******************************************************************************/

int32_t main(void)
{
    // 使能外设时钟
    HAL_SYSCTRL_FLASH_CLK_ENABLE();

    // 初始化SysTick
    HAL_InitTick(4000000);

    // 板载LED初始化
    Bsp_Led_Init();

    // 调用Slib库，检查用户变量是否读取正确
    uint32_t Slib_UserValue = SlibApi_GetValue();
    if (Slib_UserValue != 0x12345678)
    {
        Led_Tog_Error();
    }

    // 调用Slib库，检查写入FLASH是否成功
    if (WRITE_VAL != SlibApi_WriteWord((void*)WRITE_ADDR, WRITE_VAL))
    {
        Led_Tog_Error();
    }

    // 调用Slib库，检查读取FLASH是否成功
    if (WRITE_VAL != SlibApi_ReadWord((void*)WRITE_ADDR))
    {
        Led_Tog_Error();
    }

    // 调用Slib库，检查页擦是否成功
    if (SlibApi_ErasePage((void*)WRITE_ADDR, (void*)(WRITE_ADDR)))
    {
        Led_Tog_Error();
    }
    uint32_t pageEndAddr    = (WRITE_ADDR / FLASH_PAGE_SIZE + 1) * FLASH_PAGE_SIZE;
    uint32_t WordCntRemain  = FLASH_PAGE_SIZE / 4;
    while (WordCntRemain)
    {
        if (0xFFFFFFFFU != SlibApi_ReadWord((void*)(pageEndAddr - (WordCntRemain--)*4)))
        {
             Led_Tog_Error();
        }
    }

    SlibApi_Led_Blink();
}

static void Led_Tog_Error(void)
{
    while (1)
    {
        BSP_LED_TOG();
        HAL_Delay(400);
    }
}

/*******************************************************************************
 ** EOF (not truncated)
 ******************************************************************************/
#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
    /* USER CODE BEGIN */
    /* User can add his own implementation to report the file name and line number,
       tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    /* USER CODE END */
}
#endif /* USE_FULL_ASSERT */


/************************ (C) COPYRIGHT SIYIMicro *****END OF FILE*************/
